package com.xtck.ha.fault.modules.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xtck.ha.fault.framework.page.PageResult;
import com.xtck.ha.fault.framework.query.Query;
import com.xtck.ha.fault.framework.utils.DoshellUtils;
import com.xtck.ha.fault.framework.utils.FileInfosUtils;
import com.xtck.ha.fault.framework.utils.GetPidUtil;
import com.xtck.ha.fault.framework.utils.JsonResult;
import com.xtck.ha.fault.modules.convert.ModInfoConvert;
import com.xtck.ha.fault.modules.dao.ModInfoDAO;
import com.xtck.ha.fault.modules.pojo.dto.ModInfoDTO;
import com.xtck.ha.fault.modules.pojo.entity.ModInfo;
import com.xtck.ha.fault.modules.pojo.vo.ModInfoVO;
import com.xtck.ha.fault.modules.service.ModInfoService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
* @Description: ModInfoService实现类
* @author liuyuan
* @date 2025-06-17
*/
@Service
@AllArgsConstructor
@Slf4j
public class ModInfoServiceImpl extends ServiceImpl<ModInfoDAO, ModInfo>  implements ModInfoService {
        @Autowired
        private ModInfoDAO modInfoDAO;
        /**
        * 获取分页对象
        * @param query   分页参数
        */
        protected IPage<ModInfo> getPage(Query query) {
                Page<ModInfo> page = new Page<ModInfo>(query.getPage(), query.getLimit());
                // 排序
                if(StringUtils.isNotBlank(query.getOrder())){
                        if(query.isAsc()) {
                                return page.addOrder(OrderItem.asc(query.getOrder()));
                        }else {
                                return page.addOrder(OrderItem.desc(query.getOrder()));
                        }
                }
                return page;
        }
        @Override
        public PageResult<ModInfoVO> page(ModInfoDTO query) {
                IPage<ModInfo> page = modInfoDAO.selectPage(getPage(query), getWrapper(query));
                return new PageResult<ModInfoVO>(ModInfoConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
        }

        private QueryWrapper<ModInfo> getWrapper(ModInfoDTO query){
                QueryWrapper<ModInfo> wrapper = new QueryWrapper<>();
                wrapper.orderByAsc("create_time");

                return wrapper;
        }

        @Override
        @Transactional(rollbackFor = Exception.class)
        public JsonResult<String> add(ModInfoVO vo, MultipartFile algorithmFile) {
                ModInfo entity = ModInfoConvert.INSTANCE.convert(vo);
                /**检查模型名称是否重复*/
                List<ModInfo> list = modInfoDAO.selectByModName(vo.getModName());
                if (null != list && list.size() != 0)
                        return JsonResult.error("模型名称不能重复！");
                else {
                        // 上传文件
                        if (BeanUtil.isEmpty(algorithmFile)) {
                                return JsonResult.error("模型文件不能为空");
                        }
                        String filePath = null;
                        try {
                                if (algorithmFile.getOriginalFilename().endsWith("zip"))
                                        filePath = FileInfosUtils.uploadZip(algorithmFile);
                                else
                                        filePath = FileInfosUtils.uploadFile(algorithmFile);
                        } catch (Exception e) {
                                return JsonResult.error(e.getMessage());
                        }
                        entity.setModPath(filePath);
                        entity.setServerState(false);
                        entity.setCreateTime(new Date());
                        baseMapper.insert(entity);
                        return JsonResult.ok("模型新建成功");
                }
        }

        @Override
        @Transactional(rollbackFor = Exception.class)
        public ModInfo save(ModInfoVO vo) {
                ModInfo entity = ModInfoConvert.INSTANCE.convert(vo);
                baseMapper.insert(entity);
                return entity;
        }

        @Override
        @Transactional(rollbackFor = Exception.class)
        public ModInfo update(ModInfoVO vo) {
                ModInfo entity = ModInfoConvert.INSTANCE.convert(vo);
                entity.setUpdateTime(new Date());
                updateById(entity);
                return entity;
        }

        @Override
        @Transactional(rollbackFor = Exception.class)
        public void delete(List<Long> idList) {
                removeByIds(idList);
        }

        /**
         * 启动模型服务
         * @param modInfo 模型信息
         * @return 结果日志
         */
        @Override
        public JsonResult<String> startAlgorithmServer(ModInfo modInfo){
                ModInfo entity = modInfoDAO.selectById(modInfo.getId());
                List<String> paramlist = new ArrayList<>();
                paramlist.add(entity.getModPath() + "/" + entity.getStartServiceFile());
                DoshellUtils.onCall("python",paramlist);
                entity.setServerState(true);
                updateById(entity);
                return JsonResult.ok("模型服务启动");
        }

        /**
         * 停止模型服务
         * @param modInfo 模型实体
         * @return 结果日志
         */
        @Override
        public JsonResult<String> stopAlgorithmServer(ModInfo modInfo){
                ModInfo entity = modInfoDAO.selectById(modInfo.getId());
                String closeResult = "";
                try {
                        closeResult = GetPidUtil.stopByPid(entity.getModPath() + "/" + entity.getStartServiceFile());
                        entity.setServerState(false);
                        updateById(entity);
                }catch (Exception e){
                        e.printStackTrace();
                }
                log.info("模型服务停止,"+closeResult);
                return JsonResult.ok("模型服务停止,"+closeResult);
        }

        @Override
        public List<ModInfo> getAllMod() {
                return modInfoDAO.selectAll();
        }

}